﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Dapper;

namespace Dapper.Library
{
    /// <summary>
    /// 查询
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class Query<T> : AbstractSet, IQuery<T>
    {
        protected Query(IDbConnection dbCon, SqlProvider sqlProvider) : base(dbCon, sqlProvider)
        {
        }
        protected Query(IDbConnection dbCon, SqlProvider sqlProvider, IDbTransaction dbTransaction) : base(dbCon, sqlProvider, dbTransaction)
        {
        }

        /// <summary>
        /// 获取一条信息
        /// </summary>
        /// <returns></returns>
        public T Single()
        {
            T result;
            SqlProvider.FormatToSingle<T>();
            result = DbCon.QueryFirstOrDefault<T>(SqlProvider.SqlString, SqlProvider.Params, DbTransaction);

            SqlProvider.SetContext = new SetContext();
            SqlProvider.Params = new DynamicParameters();

            return result;

        }

        /// <summary>
        /// 异步获取一条信息
        /// </summary>
        /// <returns></returns>
        public async Task<T> SingleAsync()
        {
            T result;
            SqlProvider.FormatToSingle<T>();
            result = await DbCon.QueryFirstOrDefaultAsync<T>(SqlProvider.SqlString, SqlProvider.Params, DbTransaction);

            SqlProvider.SetContext = new SetContext();
            SqlProvider.Params = new DynamicParameters();

            return result;
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <returns></returns>
        public List<T> Multiple()
        {
            List<T> result;
            SqlProvider.FormatToList<T>();


            // 如果泛型类型是字典，分页结果里面的泛型集合就是字典集合，否则就是设定的泛型类型集合
            var interfaceType = typeof(T).GetInterface("IDictionary");
            if (typeof(T).Name.IndexOf("IDictionary") >= 0 || interfaceType != null)
            {
                //随意抽一条取最大条数记录
                var ret = DbCon.Query(SqlProvider.SqlString, SqlProvider.Params, DbTransaction).
                            Select(m => ((IDictionary<string, object>)m).ToDictionary(pi => pi.Key, pi => pi.Value)).
                            ToList<IDictionary<string, object>>();

                if (ret.Count > 0)
                {
                    // 随意抽一条取最大条数记录
                    result = ret.Select(m => (T)m).ToList();
                }
                else
                {
                    result = new List<T>();
                }
            }
            else
            {
                result = DbCon.Query<T>(SqlProvider.SqlString, SqlProvider.Params, DbTransaction) .ToList();
            }

            SqlProvider.SetContext = new SetContext();
            SqlProvider.Params = new DynamicParameters();

            return result;
        }

        /// <summary>
        /// 异步获取列表
        /// </summary>
        /// <returns></returns>
        public async Task<IEnumerable<T>> MultipleAsync()
        {
            IEnumerable<T> result;
            SqlProvider.FormatToList<T>();
            result = await DbCon.QueryAsync<T>(SqlProvider.SqlString, SqlProvider.Params, DbTransaction);

            SqlProvider.SetContext = new SetContext();
            SqlProvider.Params = new DynamicParameters();

            return result;
        }

        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public PageInfo<T> PageList(int pageIndex, int pageSize)
        {
            PageInfo<T> result;
            SqlProvider.FormatToPageList<T>(pageIndex, pageSize);

            // 如果泛型类型是字典，分页结果里面的泛型集合就是字典集合，否则就是设定的泛型类型集合
            var interfaceType = typeof(T).GetInterface("IDictionary");

            var pageTotal = 0;

            var itemList = new List<T>();

            if (typeof(T).Name.IndexOf("IDictionary") >= 0 || interfaceType != null)
            {
                //随意抽一条取最大条数记录
                var ret = DbCon.Query(SqlProvider.SqlString, SqlProvider.Params, DbTransaction).
                                   Select(
                                         m =>((IDictionary<string, object>)m).ToDictionary(pi => pi.Key, pi => pi.Value)).
                                   ToList<IDictionary<string, object>>();

                if (ret.Count > 0)
                {
                    // 随意抽一条取最大条数记录
                    pageTotal = Convert.ToInt32(ret[0]["MaxCount"]);
                    itemList = ret.Select(m => (T)m).ToList();
                }
                else
                {
                    itemList = new List<T>();
                }
                result = new PageInfo<T>(pageIndex, pageSize, pageTotal, itemList);
            }
            else
            {
                using (var queryResult = DbCon.QueryMultiple(SqlProvider.SqlString, SqlProvider.Params, DbTransaction))
                {
                    pageTotal = queryResult.ReadFirst<int>();

                    itemList = queryResult.Read<T>().ToList();

                    result = new PageInfo<T>(pageIndex, pageSize, pageTotal, itemList);
                }
            }

            SqlProvider.SetContext = new SetContext();
            SqlProvider.Params = new DynamicParameters();

            return result;
        }
    }
}
